﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Text;
using SpiderContract;
using System.ServiceModel;
using System.Threading;
using Common;
using System.Diagnostics;

namespace SpiderClient
{
	static class Program
	{
		/// <summary>
		/// 应用程序的主入口点。
		/// </summary>
		[STAThread]
		static void Main()
		{
			string email = String.Empty;
			string pwd = String.Empty;

			Console.Write("请输入Email：");
			email = Console.ReadLine();

			Console.Write("请输入密码：");
			pwd = Console.ReadLine();

			/*
			ConsoleKey key;
			while ((key = Console.ReadKey(true).Key) != ConsoleKey.Enter)
			{
				pwd += key.ToString();
				Console.Write("*");
			}
			 * */
			/*
			email = "test@test.com";
			pwd = "123456";
			 * */

			CrawlJobInfo[] jobs = null;
			if (VerifyUser(email, pwd, out jobs))
			{
				if (jobs == null)
				{
					Console.Write("你还未创建项目，按任意键退出...");
					Console.ReadKey();
				}
				else
				{
					Thread t = new Thread(Proc);
					t.IsBackground = true;
					t.Start(jobs);
					while (Console.ReadKey().Key != ConsoleKey.Escape)
					{
					}
				}
			}
			else
			{
				Console.Write("用户验证失败，按任意键退出...");
				Console.ReadKey();
			}
		}

		public static void Proc(object objJobs)
		{
			string errMsg = null;
			LinkInfo link = null;
			PageDataInfo data = null;
			CrawlJobInfo[] jobs = (CrawlJobInfo[])objJobs;
			while (true)
			{
				foreach (CrawlJobInfo job in jobs)
				{
					try
					{
						link = PopLinkFromWaitQueue(job.JobId);
						if (link == null)
						{
							continue;
						}

						Console.WriteLine(DateTime.Now.ToString() + "-正在采集：" + link.Url);

						data = new PageDataInfo();
						data.CpuTime = 0;
						data.JobId = job.JobId;
						data.Url = link.Url;
						data.Html = GetWeb(link.Url, job.Encoding, null, out data.CpuTime, out errMsg);
						if (!string.IsNullOrEmpty(errMsg))
						{
							Console.WriteLine(DateTime.Now.ToString() + "-采集失败：" + link.Url + "，错误：" + errMsg);
						}
						else
						{
							Console.WriteLine(DateTime.Now.ToString() + "-采集成功：" + link.Url);
						}
						PushPageData(data);
					}
					catch(Exception e)
					{
						Console.WriteLine(e.ToString());
					}
				}
			}
		}

		public static bool VerifyUser(string email, string pwd, out CrawlJobInfo[] jobs)
		{
			using (ChannelFactory<ISpiderService> channelFactory = new ChannelFactory<ISpiderService>("TK.SpiderService"))
			{
				ISpiderService spider = channelFactory.CreateChannel();
				return spider.VerifyUser(email, pwd, out jobs);
			}
		}

		public static LinkInfo PopLinkFromWaitQueue(int jobId)
		{
			using (ChannelFactory<ISpiderService> channelFactory = new ChannelFactory<ISpiderService>("TK.SpiderService"))
			{
				ISpiderService spider = channelFactory.CreateChannel();
				return spider.PopLinkFromWaitQueue(jobId);
			}
		}

		public static void PushPageData(PageDataInfo data)
		{
			using (ChannelFactory<ISpiderService> channelFactory = new ChannelFactory<ISpiderService>("TK.SpiderService"))
			{
				ISpiderService spider = channelFactory.CreateChannel();
				spider.PushPageData(data);
			}
		}

		private static string GetWeb(string url, string encoding, string cookie, out int cpuTime, out string errMsg)
		{
			cpuTime = 0;
			errMsg = null;
			string html = null;
			HttpWebResponse response = null;
			StreamReader stream = null;
			Stopwatch sw = new Stopwatch();
			sw.Start();
			try
			{
				HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
				webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.83 Safari/537.1";
				webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
				webRequest.Referer = url;
				webRequest.Headers.Add("Cache-Control", "max-age=0");
				webRequest.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
				webRequest.Credentials = CredentialCache.DefaultCredentials;
				webRequest.KeepAlive = true;
				if (string.IsNullOrEmpty(cookie))
				{
					webRequest.Headers.Add("Cookie", cookie);
				}

				webRequest.ReadWriteTimeout = 30 * 1000;
				response = (HttpWebResponse)webRequest.GetResponse();
				if (response.StatusCode == HttpStatusCode.OK)
				{
					stream = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
					html = stream.ReadToEnd();
				}
			}
			catch (Exception ex)
			{
				errMsg = ex.ToString();
				throw ex;
			}
			finally
			{
				if (response != null)
					response.Close();

				if (stream != null)
					stream.Close();
			}

			sw.Stop();
			cpuTime = (int)sw.ElapsedMilliseconds;
			return html;
		}
	}
}
